/**
 * Document   : storage in session
 * Created on : Mar 15, 2013, 5:02:58 PM
 * Author     : duonghung1369
 * 
 * */

//+++++++++++++++ HTML METHOD ++++++++++++++++++++++

/**
 * check that amount in cart and quantity in db for display or display sold out
 * image in index page
 */
function updateDisplayProduct(){
    // get divs product-block in
    var productElements = document.getElementsByClassName('product-block');
    var productId;
    var amount;
    var index;
    var amountInStock;
    try{
        for (i = 0; i < productElements.length; i++) {
            productId = productElements[i].getElementsByClassName('item-information-id')[0].innerHTML.trim();
            index = cartObj.getIndexOfItem(productId);
            var displayQuantity = productElements[i].getElementsByClassName('item-information-quantity')[0].innerHTML;
            if(index != ERROR){ // product exist in cart, get amount
                amount = Number(cartObj.items[index].amount);
                amountInStock = Number(cartObj.items[index].item.quantity);
                
                if(amount >= amountInStock){
                    // show image out of stock
                    productElements[i].className += ' ' + "block-sold-out";

                    // decrease opacity of img tag
                    productElements[i].getElementsByTagName('img')[0].className = "image-sold-out";

                    // update lable quantity information
                    productElements[i].getElementsByClassName('item-information-quantity')[0].innerHTML = 0;
                }else{
                    // remove class name block-sold-out
                    productElements[i].className = productElements[i].className.split(" ")[0];

                    // remove opacity of img tag
                    productElements[i].getElementsByTagName('img')[0].className = "";

                    // update lable quantity information
                    productElements[i].getElementsByClassName('item-information-quantity')[0].innerHTML = amountInStock - amount;
                }
            } else { // no product in cart
                if(Number(displayQuantity) == 0){
                    // show image out of stock
                    productElements[i].className += ' ' + "block-sold-out";

                    // decrease opacity of img tag
                    productElements[i].getElementsByTagName('img')[0].className = "image-sold-out";
                }else{
                    // remove class name block-sold-out
                    productElements[i].className = productElements[i].className.split(" ")[0];

                    // remove opacity of img tag
                    productElements[i].getElementsByTagName('img')[0].className= "";
                }
            }
        }
    }catch(err){
        console.log(err);
    }
}

//+++++++++++++++ GLOBAL VARIABLES +++++++++++++++++
var cartObj = new ShoppingCart();
var CART = 'cart';
var ERROR = -1;
var DISABLE = 'disable';


//+++++++++++++++ PUBLIC METHOD ++++++++++++++++++++

/**
 * Add an product to shopping cart (index page), then store shopping cart object to sessionStorage.
 */
function addCart(id, name, desc, quantity, price, link){
    if(quantity <= 0) {
        return;
    }
    var check = isStillProductInStock(id, quantity);
    if(check){
        var product = new Product(id, name, desc, quantity, price, link);
        var cartItem = new ShoppingCartItem(1, product);
        cartItem.price = price;
        cartObj.addToCart(cartItem)
        // store cart to sessionStorage
        storeCartToSession(cartObj);
    }

    
    updateIndexPage();

    console.log('addCart: ' + JSON.stringify(cartObj));
}

/**
 * Add to cart when in detail page.
 */
function addToCart(id, name, desc, quantity, price, link){
    if(quantity <= 0) {
        return;
    }
    var check = isStillProductInStock(id, quantity);
    if(check){
        var product = new Product(id, name, desc, quantity, price, link);
        var cartItem = new ShoppingCartItem(1, product);
        cartItem.price = price;
        cartObj.addToCart(cartItem)
        // store cart to sessionStorage
        storeCartToSession(cartObj);
    }
    
    updateDetailPage()
}

/**
 * Get JSON from sessionStorage.getItem(CART),
 * then set value fo cartObj.
 */
function convertJSONToCart(JSONstring){
    if(!JSONstring){
        console.log('JSONstring  undefined: ' + JSONstring);
        return;
    }
    
    try{
        console.log(JSONstring);

        var obj = JSON.parse(JSONstring);
        cartObj.total = obj.total;
        cartObj.number_of_items = obj.number_of_items;
        cartObj.items = obj.items;
    }catch (err){
        console.log("Can't parse JSONstring to object");
        alert(err);
    }
}

/**
 * Update cartObj and label of cart index page.
 */
function updateIndexPage(){
    // update value for cartObj
    convertJSONToCart(sessionStorage.getItem(CART));

    // update label
    updateNumberOfItem(cartObj.calculateNumberOfItems());

    // check that amount in cart and quantity in db for display or
    // not display a product
    updateDisplayProduct();
}

/**
 * Called when window.onready in detail page of product or when user click add to cart button
 * in detail page.
 */
function updateDetailPage(){
    // update value for cartObj
    convertJSONToCart(sessionStorage.getItem(CART));

    // update still quantity that user can buy from session
    var productId = Number(document.getElementById("productInformation-id").innerHTML);
    var amountInStock = Number(document.getElementById("productInformation-quantity").innerHTML);
    index = cartObj.getIndexOfItem(productId);
    if(index != ERROR){ // product exist in cart, get amount
        amount = Number(cartObj.items[index].amount);
        amountInStock = Number(cartObj.items[index].item.quantity);

        if(amount >= amountInStock){
            // hide add to cart button
            document.getElementById("productInformation-addCart").className += DISABLE;
            
            // set quantity in detail page to 0
            document.getElementById('productInformation-quantity').innerHTML = 0;
        }else{
            // remove class name disable
            document.getElementById("productInformation-addCart").className = "";

            // update lable quantity information
            document.getElementById("productInformation-quantity").innerHTML = amountInStock - amount;
        }
    } else { // product not in cart, check quantity
        if(amountInStock == 0) { // if current amount of product in db is 0, then prevent add to cart anymore
            // hide add to cart button
            document.getElementById("productInformation-addCart").className += DISABLE;
        }
    }

    // update number of item label
    updateNumberOfItem(cartObj.calculateNumberOfItems());
}

/**
 * Update information about cart from sessionStorage.
 */
function updateViewCartPage(){
    // update value for cartObj from storage.
    convertJSONToCart(sessionStorage.getItem(CART));

    // check if cart not have any item
    if(cartObj.calculateNumberOfItems() == 0){
        document.getElementById("view_cart_form").innerHTML = "";

        // update number of item label
        updateNumberOfItem(cartObj.calculateNumberOfItems());

        document.getElementById("number_cart_items").innerHTML = cartObj.number_of_items;

        return;
    }

    var form = document.getElementById("view_cart_form");
    var tbody = form.getElementsByTagName("tbody")[0];

    var body_content = '';
    // add content rows for tbody
    var cart_item = null;
    for (var i = 0; i < cartObj.items.length; i++) {
        cart_item = cartObj.items[i];
        if(i % 2 == 0){
            body_content += '<tr class="row-even">';
        }else{
            body_content += '<tr class="row-odd">';
        }
        body_content += '<td style="display: none"><input type="hidden" value="' + cart_item.item.id + '" /></td>';
        body_content += '<td>' + (i + 1) + '</td>';
        body_content += '<td>' + cart_item.item.name + '</td>';
        body_content += "<td><img style='width: 300px;' src='" + cart_item.item.link + "' /></td>";
        body_content += '<td>' + cart_item.item.desc + '</td>';
        if(cart_item.item.quantity < cart_item.amount){
            cart_item.amount = cart_item.item.quantity;
        }
        body_content += '<td>' + generateSelectTag(1, cart_item.item.quantity, cart_item.amount) + '</td>';
        body_content += '<td>' + cart_item.item.price + '</td>';
        body_content += '<td>' + (cart_item.amount * cart_item.item.price) + '</td>';
        body_content += '<td><a class="delete-item" href="#" onclick="deleteItemFromCart(this);" style="text-decoration: none; display:block; width:100%; heigh: 100%;"></a></td>';
        body_content += '<input type="hidden" style="display:none" name="cartXML" id="input-cartXML" />'
        body_content += '</tr>';
    }

    // row sum total
    body_content += '<tr style="font-weight: bold; text-align: center; background-color: cyan;">';
    body_content += '<td colspan="6" >Total</td>';
    body_content += '<td>' + cartObj.calculateTotal() + '</td>';
    body_content += '<td></td>';
    body_content += '</tr>';

    // add last row contain 2 link
    body_content += '<tr>';
    body_content += '<td colspan="4"></td>';
    body_content += '<td colspan="2"><a class="continue-shopping" href="../product/index.html"></a></td>';
    body_content += '<td colspan="2"><input type="submit" value="" class="check-out"></a></td>';
    //    body_content += '<td colspan="2"><a class="check-out" href="../cart/checkout.html"></a></td>';

    // using ajax
    //    body_content += '<td colspan="2"><a class="check-out" href="#" onclick="checkProductQuantity()"></a></td>';
    body_content += '</tr>';

    tbody.innerHTML = body_content;

    // set hidden XML of cart value for server.
    document.getElementById("input-cartXML").value = convertProductToXML(cartObj.items);

    // update number of item label
    updateNumberOfItem(cartObj.calculateNumberOfItems());

    document.getElementById("number_cart_items").innerHTML = cartObj.number_of_items;

    // store cartObj to session
    storeCartToSession(cartObj);
}

function updateCheckOutPage(){
    // update value for cartObj
    convertJSONToCart(sessionStorage.getItem(CART));

    // update number of item label
    updateNumberOfItem(cartObj.calculateNumberOfItems());

    document.getElementById("input-checkout-cartXML").value = convertProductToXML(cartObj.items);

    // append cartXML to hidden input send to server
    document.getElementById('input-checkout-customCartXML').value = convertItemsToXML(cartObj.items);
}

/**
 * After checkout successfull, clear cart.
 */
function updateConfirmationPage(){
    // update value for cartObj
    convertJSONToCart(sessionStorage.getItem(CART));

    // store cart XML to hidden field
    document.getElementById('input-confirmation-customCartXML').value = convertItemsToXML(cartObj.items);
    
    // clear cart
    cartObj = new ShoppingCart();

    // clear session
    sessionStorage.clear();

    // reset cart number item = 0
    updateNumberOfItem(0);
}
/**
 * Update view_cart page when user change item quantity.
 */
function updateCartQuantity(nodeQuantity){
    var nodeRow = nodeQuantity.parentNode.parentNode;
    var columnsNode = nodeRow.getElementsByTagName('td');

    // get hidden productId
    var productId = columnsNode[0].getElementsByTagName('input')[0].value;

    // get item quantity
    var currentQuantity = columnsNode[5].getElementsByTagName('select')[0].value;

    var price = columnsNode[5].innerHTML.trim();

    var newProduct = new Product();
    newProduct.id = productId;
    var newCartItem = new ShoppingCartItem(currentQuantity, newProduct);
    newCartItem.price = price;

    // update cart
    var updateResult = cartObj.updateCart(newCartItem);

    if(!updateResult){
        alert('Sorry! Only ' + cartObj.items[cartObj.getIndexOfItem(productId)].item.quantity + ' items of this product!');
        return false;
    }

    // store cartObj to sessionStorage
    storeCartToSession(cartObj);

    updateViewCartPage();
    return true;
}

function deleteItemFromCart(nodeDelete){
    var nodeRow = nodeDelete.parentNode.parentNode;
    var columnsNode = nodeRow.getElementsByTagName('td');

    // get hidden productId
    var productId = columnsNode[0].getElementsByTagName('input')[0].value;
    cartObj.deleteItemFromCart(productId);

    storeCartToSession(cartObj);
    updateViewCartPage();
}


/**
 * Convert a cart object to JSON format and store in sessionCart.
 *
 */
function storeCartToSession(cart){
    try{
        var JSONstring = JSON.stringify(cart);
        // store cart to sessionStorage
        sessionStorage.setItem(CART, JSONstring);
    }catch(err){
        alert(arr);
    }
}

/**
 * Check if browser support web storage or not.
 */
function checkSupportStorage(){
    return (typeof(Storage) !== "undefined");
}

/**
 * Update label cart item on the top.
 */
function updateNumberOfItem(number){
    if(document.getElementById('numberCartItems')) {
        document.getElementById('numberCartItems').innerHTML = number;
    }
}


//++++++++++++++++++++++ DEFINE CLASSES +++++++++++++++++++

/**
 * Define class Product.
 */
function Product (id, name, desc, quantity, price, link){
    this.id = null;
    this.name = null;
    this.desc = null;
    this.quantity = null;
    this.price = null;
    this.link = null;

    if(arguments.length == 6){
        this.id = id;
        this.name = name;
        this.desc = desc;
        this.quantity = quantity;
        this.price = price;
        this.link = link;
    }
}

/**
 * Define class ShoppingCart class.
 */
function ShoppingCart(){
    this.total = 0;
    this.number_of_items = 0;
    this.items = new Array();

    this.addToCart = function(cartItem){
        var index = this.getIndexOfItem(cartItem.item.id);

        // item has been already in cart
        if(index != ERROR){
            this.items[index].amount++;
        }else{
            this.items.push(cartItem);
        }

        this.number_of_items++;

        updateNumberOfItem(this.number_of_items);
    };

    this.updateCart = function(cartItem){
        var index = this.getIndexOfItem(cartItem.item.id);
        if(index != ERROR){
            var item = this.items[index];
            
            // if update cart amount more than quantity in DB
            //            if(cartItem.amount > item.item.quantity){
            //                return false;
            //            }else{
            item.amount = cartItem.amount;
            return true;
        //            }
        }

        return false;
    }

    this.deleteItemFromCart = function(id){
        var index = this.getIndexOfItem(id);
        this.items.splice(index, 1);
    }

    this.containItem = function(cartItem){
        for (var i = 0; i < this.items.length; i++) {
            if(this.items[i].item.id == cartItem.item.id){
                return this.items[i];
            }
        }

        return null;
    };

    this.calculateTotal = function(){
        this.total = 0;
        for (var i = 0; i < this.items.length; i++) {
            this.total += this.items[i].amount * this.items[i].item.price;
        }

        return this.total;
    }

    this.calculateNumberOfItems = function(){
        this.number_of_items = 0;
        for (var i = 0; i < this.items.length; i++) {
            this.number_of_items += Number(this.items[i].amount);
        }
        return this.number_of_items;
    }

    /**
     * Get index of an ShoppingCartItem from this.items depend on productId.
     */
    this.getIndexOfItem = function(id){
        for (var i = 0; i < this.items.length; i++) {
            if(this.items[i].item.id == Number(id)){
                return i;
            }
        }

        // not found
        return ERROR;
    }
}

/**
 * Define shopping cart item class.
 */
function ShoppingCartItem(amount, item){
    this.amount = 1
    this.item = null;
    this.sub_total = 0;
    this.price = 0;

    if(arguments.length == 2){
        this.amount = amount;
        this.item = item;
        if(item){
            this.sub_total = this.amount * item.price;
        }
    }
}